package pri.damai.xiaowu.usercenter.handle;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import pri.damai.xiaowu.common.core.enums.ResultCommonEnum;
import pri.damai.xiaowu.common.core.exception.GlobalException;
import pri.damai.xiaowu.common.core.handler.ValidExceptionHandler;
import pri.damai.xiaowu.common.core.vo.ResultVO;

import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理
 * @Desc
 * @Author DaMai
 * @Date 2021/9/28 17:40
 * 但行好事，莫问前程。
 */
@RestControllerAdvice
@Slf4j
public class ExceptionHandle {

    private static final ValidExceptionHandler VALID_EXCEPTION_HANDLER = new ValidExceptionHandler();

    /**
     * 兜底异常
     * @apiNote [附加描述]
     * @param e 自定义异常
     * @return com.ruiruan.userserver.vo.ResultVO<java.lang.String>
     * @author DaMai
     * @date 2021/3/23 15:32
     */
    @ExceptionHandler({Exception.class})
    public ResultVO<String> resultHandle(Exception e) {
        log.warn("服务异常。", e);
        return ResultVO.error(ResultCommonEnum.SERVER_ERROR.code(), ResultCommonEnum.SERVER_ERROR.format(e.getMessage()));
    }

    /**
     * 参数校验异常拦截
     * @apiNote
     *  对象参数接收请求体： MethodArgumentNotValidException
     *  请求参数绑定到对象参数上： BindException
     *  RequestParam上的异常是 ConstraintViolationException
     *  必填参数没传： ServletRequestBindingException
     *  必填请求参数缺失：MissingServletRequestParameterException
     *  路径参数缺失：MissingPathVariableException
     * @param e 异常
     * @return com.ruiruan.userserver.vo.ResultVO<java.lang.String>
     * @author DaMai
     * @date 2021/3/23 15:31
     */
    @ExceptionHandler({
            MethodArgumentNotValidException.class,
            ServletRequestBindingException.class,
            BindException.class,
            ConstraintViolationException.class,
            GlobalException.class,
    })
    @ResponseBody
    public ResultVO<String> handleValidationException(Exception e) {

        if (e instanceof GlobalException) {
            GlobalException ge = (GlobalException) e;
            log.warn("业务异常。{}", e.getMessage());
            return ResultVO.error(ge.getCode(), ge.getMessage());
        }

        return VALID_EXCEPTION_HANDLER.handle(e);
    }
}
